//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

// Copyright (c) 2002 BSQUARE Corporation.  All rights reserved.
// DO NOT REMOVE --- BEGIN EXTERNALLY DEVELOPED SOURCE CODE ID 40973--- DO NOT REMOVE

// Bus driver definitions

#include "SDCardDDK.h"
#include "SDMisc.h"
#ifndef _SDCARD_BUSDRIVER_DEFINED
#define _SDCARD_BUSDRIVER_DEFINED

#define SDCARD_INTERFACE_OVERRIDE_1BIT 0
#define SDCARD_INTERFACE_OVERRIDE_4BIT 1


#define SDCARD_DEFAULT_REQUEST_LIST_DEPTH   32
#define DEFAULT_THREAD_PRIORITY             100
#define DEFAULT_MEMORY_TAGS                 6
#define DEFAULT_MESSAGE_ENTRIES             7
#define DEFAULT_REFCOUNT_WAIT               100
#define DEFAULT_MAX_WAIT_COUNT              20
#define DEFAULT_BUS_REQUEST_RETRY_COUNT     3
#define DEVICE_CLEANUP_POLLING_INTERVAL     100
#define POWER_RESUME_POLLING_INTERVAL       1000
#define POWER_RESUME_DELAY_INTERVAL         2000

typedef enum SD_CARD_STATE {
    INACTIVE = 0,          //Inactive Mode
    IDLE,                  //Card Identification Mode
    READY,
    IDENTIFICATION,
    STAND_BY,              //Data Transfer Mode
    TRANSFER,
    SENDING,
    RECIVING,
    PROGRAMMING,
    DISCONNECT
}*PSD_CARD_STATE;


// bus request System Flags
#define SD_BUS_REQUEST_BUSY                 0x00000100      // bus request is in the HC
#define SD_BUS_REQUEST_NON_CANCELABLE       0x00000200      // bus request is non-cancelable
#define SD_BUS_REQUEST_COMPLETING           0x00000400      // bus request is being processed in dispatcher
#define SYSTEM_FLAGS_RETRY_COUNT_MASK       0x000000FF

// bus driver tag
#define SD_BUS_DRIVER_TAG  'SDBS'
// default powerup wait while polling for NOT busy
#define DEFAULT_POWER_UP_TOTAL_WAIT_TIME  2000
// as per spec , 50 MS interval
#define DEFAULT_POWER_UP_SD_POLL_INTERVAL 50
// MMC cards don't really specify this, so we'll just borrow the SD one.
#define DEFAULT_POWER_UP_MMC_POLL_INTERVAL DEFAULT_POWER_UP_SD_POLL_INTERVAL


//SD Card Post Event
#define SD_INSERTFAILED 0x0000E001
#define SD_REMOVE       0x0000E002
#define SD_INSERTOK     0x00008001

// the main class for the bus driver
class CSDBusDriver : public CDeviceDriver
{
    public:
    CARAPI Read(
        /* [in] */ Int64 u64Offset,
        /* [in] */ Int32 bytesToRead,
        /* [out] */ MemoryBuf * pBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Write(
        /* [in] */ Int64 u64Offset,
        /* [in] */ const MemoryBuf &buffer,
        /* [out] */ Int32 * pBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Control(
        /* [in] */ Handle32 nControlCode,
        /* [in] */ const MemoryBuf &inBuffer,
        /* [out] */ MemoryBuf * pOutBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    virtual void Dispose();
public:

    CSDBusDriver();
    ~CSDBusDriver();

    // initialize
    SD_API_STATUS Initialize();
    // acquire global system lock
    inline void AcquireLock() {
        WaitResult wr;
        m_CriticalSection.Lock(&wr);
    }
    // release global system lock
    inline void ReleaseLock() {
        m_CriticalSection.Unlock();
    }
    // legacy power up/down
    void BusPowerUp();
    void BusPowerDown();
    void SetupBusInterrupt(UInt8 intr);
    Boolean stopMMCClock(void);
    Boolean startMMCClock(void);
    Boolean SetClockRate(XLLP_MMC_CLKRATE Rate, Boolean ClkOn);

    SD_API_STATUS SetSDCardIdleState();
    SD_API_STATUS HandleAddDevice();
    SD_API_STATUS HandleRemoveDevice();

    SD_API_STATUS WaitForSingle(UInt32 val);
    SD_API_STATUS SDLoadDevice();
    SD_API_STATUS SDUnloadDevice();

    SD_API_STATUS CheckCardBusy(UInt32 TimeOut);
    SD_API_STATUS SDCardDataReceive( UInt8 *dBuf,
                                     UInt32 dataLength,
                                     UInt32 noBlocks);

    SD_API_STATUS SDCardDataXmit( UInt8 *dBuf,
                                  UInt32 dataLength,
                                  UInt32 noBlocks);

    SD_API_STATUS SDCardReadBlock_X(  XLLP_MMC_CMD         Command,
                                      UInt32                Argument,
                                      PSD_COMMAND_RESPONSE pResponse,
                                      UInt32                NumBlocks,
                                      UInt32                BlockSize,
                                      PUInt8               pBlockBuffer );

    SD_API_STATUS SDCardWriteBlock_X( XLLP_MMC_CMD         Command,
                                      UInt32                Argument,
                                      PSD_COMMAND_RESPONSE pResponse,
                                      UInt32                NumBlocks,
                                      UInt32                BlockSize,
                                      PUInt8               pBlockBuffer);


    SD_API_STATUS SDCardBusPrepareRequest_X( XLLP_MMC_CMD  Command,
                                             UInt32         Argument,
                                             UInt32         NumBlocks);


    SD_API_STATUS SDCardBusRequestAndResponse_X( XLLP_MMC_CMD           Command,
                                                 UInt32                  Argument,
                                                 PSD_COMMAND_RESPONSE   pResponse,
                                                 UInt32                  NumBlocks,
                                                 UInt32                  BlockSize,
                                                 PUInt8                 pBuffer );

    SD_API_STATUS SDCardResponseAndAnalysis_X( PSD_COMMAND_RESPONSE   pResponse );

    SD_API_STATUS SDCardSendAppCmd_X( XLLP_MMC_CMD         Command,
                                      UInt32                Argument,
                                      PSD_COMMAND_RESPONSE pResponse,
                                      UInt32                NumberOfBlocks,
                                      UInt32                BlockSize,
                                      PUInt8               pBlockBuffer );

    SD_API_STATUS SDCardInfoQuery_X(  SD_INFO_TYPE InfoType,
                                      PSD_COMMAND_RESPONSE pResponse,
                                      UInt32 NumBlk,
                                      UInt32 BlkSiz,
                                      UInt8 *pBuff);


public:
    DzMutex             m_CriticalSection;     // bus driver critical section
    Boolean                m_Initialized;                  // fully initialized
    Boolean                m_Powered, m_CardInsert, m_CliReg;
    UInt32               RefCnt;
    P_XLLP_GPIO_T	    m_pvGPIOReg;
    P_XLLP_MMC_T	    m_pvMMCReg;
    P_XLLP_CLKMGR_T	    m_pvClockRegs;

};

typedef CSDBusDriver * PSD_BUSD;

// Signature of SDCARD_HC_CONTEXT structure
#define VALID_HC_CONTEXT_SIG        'cHdS' // SdHc
#define DEREGISTERED_HC_CONTEXT_SIG 0xdededede

#endif
// DO NOT REMOVE --- END EXTERNALLY DEVELOPED SOURCE CODE ID --- DO NOT REMOVE

